<template>
    <section class="w-full h-full flex gap-col-4">
        <div class="w-300px box-border bg-white pa-4">
            <dept-tree ref="deptTreeRef" @select="handleSelectDept" />
        </div>
        <div class="flex-1 flex flex-col gap-row-4">
            <div class="bg-white box-border pa-4">
                <DataQuery v-model:model="queryParameter" @query="query" @reset="reset" />
            </div>
            <div class="flex-1 bg-white box-border pa-4 flex flex-col">
                <div class="w-full pb-4 box-border flex items-center justify-between">
                    <div class="inline-flex items-center gap-col-2">
                        <n-button @click="insertData" type="primary">添加数据</n-button>
                        <n-button @click="modifyUserToDept">调整部门</n-button>
                        <n-button @click="batchDeleteData">批量删除</n-button>
                    </div>
                    <TableOperator @refresh="query" v-model:list="selectList" />
                </div>

                <NDataTable
                    class="flex-1 h-full"
                    :columns="columnList"
                    :data="data"
                    :loading="loading"
                    :row-key="(row: Data) => row.identity"
                    :striped="true"
                    :bordered="true"
                    :remote="true"
                    :flex-height="true"
                    :single-line="false"
                    :pagination="pagination"
                    v-model:checked-row-keys="keyList" />
            </div>
        </div>

        <n-modal
            v-model:show="formVisible"
            :auto-focus="false"
            :close-on-esc="false"
            preset="card"
            :style="{width: '800px'}"
            :title="formTitle"
            size="large"
            :bordered="false"
            :segmented="{content: 'soft', footer: 'soft'}">
            <DataForm :identity="dataInfo.identity" :dept-id="queryParameter.deptId || dataInfo.deptId" @confirm="formConfirm" @cancel="formCancel" />
        </n-modal>

        <n-modal
            v-model:show="selectDeptVisible"
            title="批量移动用户到部门"
            :auto-focus="false"
            :close-on-esc="false"
            preset="card"
            :style="{width: '600px'}"
            size="large"
            :bordered="false"
            :segmented="{content: 'soft', footer: 'soft'}">
            <dept-tree @select="selectUserDept" />
            <template #footer>
                <div class="flex justify-end items-center gap-col-4">
                    <n-button @click="batchModifyDept" style="color: #ffffff;background: var(--app-primary-color);">确定</n-button>
                    <n-button>取消</n-button>
                </div>
            </template>
        </n-modal>
    </section>
</template>

<script setup lang="ts">
import {h, ref} from 'vue'
import {Api} from '@/api/type'
import DataForm from './form.vue'
import {UserApi} from '@/api/user'
import DataQuery from './query.vue'
import {BaseApi} from '@/api/base-api'
import {useTable} from '@/hook/use-table'
import DeptTree from '@/view/system/dept/tree.vue'
import {TableColumn} from 'naive-ui/es/data-table/src/interface'
import TableOperator from '@/component/common/table-operator.vue'
import {NButton, NDataTable, NModal, NSpace, NSwitch, useDialog, useMessage} from 'naive-ui'
// -------------------------------------------------
type R<T> = Api.Common.R<T>;
type Data = Api.System.User;
type PageRecord<T> = Api.Common.PageRecord<T>;
type PageParameter = Api.Common.PageParameter<Data>;
// -------------------------------------------------
const dialog = useDialog()
const message = useMessage()
const userApi = new UserApi()
const baseApi = new BaseApi<Data>('user')
const dataInfo = ref<Partial<Data>>({})
const formTitle = ref<string>('')
const formVisible = ref<boolean>(false)
const targetDeptId = ref<string>('')
const selectDeptVisible = ref<boolean>(false)

const {
    data,
    loading,
    getData,
    keyList,
    columnList,
    selectList,
    pagination,
    queryParameter,
    resetParameter
} = useTable<Data, TableColumn<Data>>({
    queryFn: async (query: PageParameter): Promise<R<PageRecord<Data>>> => {
        let result: R<PageRecord<Data>> = await baseApi.getPageInfo(query)
        if (result.code == 0) {
            return result
        } else {
            throw Error(result.message)
        }
    },
    queryParameter: {
        username: '',
        nickname: '',
        mobile: '',
        status: ''
    },
    columnList: () => [
        {
            type: 'selection',
            title: '选择列',
            align: 'center',
            titleAlign: 'center',
            width: 50
        },
        {
            title: '序号',
            key: 'index',
            align: 'center',
            titleAlign: 'center',
            width: 80
        },
        {
            title: '登录账号',
            key: 'username',
            align: 'left',
            titleAlign: 'center'
        },
        {
            title: '账号名称',
            key: 'nickname',
            align: 'center',
            titleAlign: 'center'
        },
        {
            title: '手机号',
            key: 'mobile',
            align: 'center',
            titleAlign: 'center'
        },
        {
            title: '是否启用',
            key: 'status',
            align: 'center',
            titleAlign: 'center',
            render(row: Data) {
                return h(NSwitch, {
                    'size': 'small',
                    'default-value': row.status,
                    'checked-value': 1,
                    'unchecked-value': 0,
                    'on-update:value': (value: 0 | 1) => switchStatus(row.identity, value)
                })
            }
        },
        {
            title: '登录IP地址',
            key: 'loginIp',
            align: 'center',
            titleAlign: 'center'
        },
        {
            title: '最后登录时间',
            key: 'loginTime',
            align: 'center',
            titleAlign: 'center'
        },
        {
            title: '操作',
            key: 'operate',
            width: '160',
            align: 'center',
            titleAlign: 'center',
            render(row: Data) {
                return h(NSpace, {'justify': 'space-around'}, {
                        default: () => [
                            h(NButton, {onClick: () => updateData(row), size: 'small', type: 'primary', strong: true, secondary: true}, {default: () => '修改'}),
                            h(NButton, {onClick: () => deleteData(row), size: 'small', type: 'error', strong: true, secondary: true}, {default: () => '删除'})
                        ]
                    }
                )
            }
        }
    ] as TableColumn<Data>[]
})

/**
 * 选择部门
 */
async function handleSelectDept(parent: {key: string | number; label: string;}) {
    console.info('选择的部门:', parent)
    queryParameter.deptId = String(parent.key || '')
    await getData()
}

async function reset() {
    resetParameter()
    await getData()
}

async function query() {
    await getData()
}

/**
 * 添加数据
 */
async function insertData() {
    dataInfo.value = {}
    formTitle.value = '添加数据'
    formVisible.value = true
}

/**
 * 更新数据
 */
async function updateData(item: Data) {
    dataInfo.value = item
    formTitle.value = '修改数据'
    formVisible.value = true
}

/**
 * 单条数据删除
 */
async function deleteData(item: Data) {
    await new Promise((resolve, reject) => {
        dialog.warning({
            title: '提示',
            content: '确定要删除选中数据?',
            positiveText: '确定',
            negativeText: '取消',
            onPositiveClick: () => resolve(true),
            onNegativeClick: () => reject(false)
        })
    }).then(async () => {
        let result = await baseApi.removeData(item.identity)
        if (result.code == 0) {
            message.success('删除数据成功.')
        } else {
            message.error('删除数据失败.' + (result.message || ''))
        }
    }).finally(async () => {
        await getData()
    })
}

/**
 * 批量删除数据
 */
async function batchDeleteData() {
    if (keyList.value.length == 0) {
        message.error('请先选择要删除的数据后再试')
        return false
    }
    await new Promise((resolve, reject) => {
        dialog.warning({
            title: '提示',
            content: '确定要删除选中数据?',
            positiveText: '确定',
            negativeText: '取消',
            onPositiveClick() {
                resolve(true)
            },
            onNegativeClick() {
                reject(false)
            }
        })
    }).then(async () => {
        let result = await baseApi.batchRemoveData(keyList.value)
        if (result.code == 0) {
            message.success('删除数据成功.')
        } else {
            message.error('删除数据失败.' + (result.message || ''))
        }
    }).finally(async () => {
        await getData()
    })
}

/**
 * 批量修改用户部门
 */
async function modifyUserToDept() {
    let userId = keyList.value || []
    if (userId.length == 0) {
        message.error('请先选择要调整的用户后再试')
        return false
    }
    selectDeptVisible.value = true
}

/**
 * 批量修改部门
 */
async function selectUserDept(parent: {key: string | number; label: string;}) {
    targetDeptId.value = String(parent.key || '')
}

async function batchModifyDept() {
    let userId = keyList.value || []
    if (userId.length == 0) {
        message.error('请先选择要调整的用户后再试')
        return false
    }
    let deptId = String(targetDeptId.value)
    if (!deptId) {
        message.error('请先选择部门后再试')
        return false
    }
    let result = await userApi.batchModifyUserDept(deptId, userId)
    if (result.code == 0) {
        message.success('批量修改用户部门成功')
    } else {
        message.error(`批量修改用户部门失败. ${result.message || ''}`)
    }
    selectDeptVisible.value = false
    await getData()
}

async function switchStatus(identity: string, status: 1 | 0) {
    await baseApi.modifyData({identity, status})
    await getData()
}

async function formConfirm() {
    formVisible.value = false
    await getData()
}

async function formCancel() {
    formVisible.value = false
    await getData()
}
</script>
